package com.hjm.java.utils;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.Base64;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.hjm.java.R;
import com.hjm.java.sql.HJMHelper;
import com.hjm.java.sql.ImgTableTool;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class HjmGlideUtil {
    private static final String TAG = "HjmGlideUtil";

    public static void UrlToBitmap(Context context, String imageUrl, String[] imgIdArr, HJMHelper hjmHelper, HjmGlideBitmapCallBack callBack, HjmGlideDoneCallBack doneCallBack) {
        Executors.newSingleThreadExecutor().submit(()-> {
            if (imgIdArr == null)
                return;

            // 获取图片id不在数据库中的图片id数组
            String[] imgIdNotInDBArr = ImgTableTool.findImgIdNotInDBArr(imgIdArr, hjmHelper);
//        for (String id:imgIdNotInDBArr)
//            Log.d(TAG, "UrlToBitmap: 没有找到的id："+id);

            // 如果所有图片id都不在数据库中，那么imgIdNotInDBArr等于imgIdArr
            if (imgIdNotInDBArr.length == imgIdArr.length) {
                Log.d(TAG, "UrlToBitmap: 图片都不存在于数据库");

                OkHttpClient client = new OkHttpClient();
                AtomicReference<Integer> tmp = new AtomicReference<>(0);

                for (int i = 0; i < imgIdArr.length; i++) {
                    getBitMapByOkHTTP(client, imageUrl + imgIdArr[i], context,
                            (isSuccess, bitmap, msg) -> {
                                if (isSuccess) {
                                    callBack.call(tmp.get(), bitmap);
                                    try {
                                        ImgTableTool.insert(imgIdArr[tmp.get()], bitmap, hjmHelper);
                                    } catch (Exception e) {
                                        Log.d(TAG, "UrlToBitmap: 插入失败");
                                    }
                                } else {
                                    callBack.call(tmp.get(), BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
                                }
                                tmp.getAndSet(tmp.get() + 1);
                                if (tmp.get() == imgIdArr.length) {
                                    doneCallBack.call();
                                }
                            });
                }
            }

            // 如果图片id都在数据库，那么就从数据库获取图片
            if (imgIdNotInDBArr.length == 0) {
                Log.d(TAG, "UrlToBitmap: 图片都存在于数据库");
                for (int i = 0; i < imgIdArr.length; i++) {
                    String imgId = imgIdArr[i];
                    Bitmap bitmap = ImgTableTool.findImgById(imgId, hjmHelper);
                    if (bitmap != null) {
                        callBack.call(i, bitmap);
                    } else {
                        callBack.call(i, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
                    }
                }
                doneCallBack.call();
            }

            // 如果图片id部分在数据库
            if (imgIdNotInDBArr.length != 0 && imgIdNotInDBArr.length != imgIdArr.length) {
                Log.d(TAG, "UrlToBitmap: 部分图片存在于数据库");
                // 将imgIdNotInDBArr转为list
                List<String> imgIdNotInDBList = Arrays.asList(imgIdNotInDBArr);

                OkHttpClient client = new OkHttpClient();

                Map<Integer, String> map = new HashMap<>();

                for (int i = 0; i < imgIdArr.length; i++) {

                    String imgId = imgIdArr[i];
                    if (!imgIdNotInDBList.contains(imgIdArr[i])) {
                        Bitmap bitmap = ImgTableTool.findImgById(imgId, hjmHelper);
                        if (bitmap != null) {
                            callBack.call(i, bitmap);
                        } else {
                            callBack.call(i, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
                        }
                    } else {
                        map.put(i, imgId);
                    }
                }

                AtomicReference<Integer> tmp = new AtomicReference<>(0);

                map.forEach((key, value) -> {
                    getBitMapByOkHTTP(client, imageUrl + value, context,
                            (isSuccess, bitmap, msg) -> {
                                synchronized (tmp) {
                                    if (isSuccess) {
                                        callBack.call(key, bitmap);
                                        // 将图片存储到数据库
                                        try {
                                            ImgTableTool.insert(value, bitmap, hjmHelper);
                                        } catch (Exception e) {
                                            Log.e(TAG, "UrlToBitmap: 保存" + value + "到数据库失败", e);
                                        }
                                    } else {
                                        Log.e(TAG, "UrlToBitmap: 获取图片失败" + msg);
                                        callBack.call(key, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
                                    }
                                    tmp.getAndSet(tmp.get() + 1);
                                    if (tmp.get() == map.size()) {
                                        doneCallBack.call();
                                    }
                                }
                            });
                });
            }
        });
    }

    /**
     * 使用OkHttpClient获取图片
     *
     * @param context      上下文
     * @param imageUrl     图片地址
     * @param imgIdArr     图片id数组
     * @param callBack     单个图片获取完成回调
     * @param doneCallBack 所有图片获取完成回调
     */
    public static void UrlToBitmap(Context context, String imageUrl, String[] imgIdArr, HjmGlideBitmapCallBack callBack, HjmGlideDoneCallBack doneCallBack) {
        OkHttpClient client = new OkHttpClient();
        AtomicReference<Integer> tmp = new AtomicReference<>(0);
        for (int i = 0; i < imgIdArr.length; i++) {
            getBitMapByOkHTTP(client, imageUrl + imgIdArr[i], context, (position, bitmap) -> {
                synchronized (tmp) {
                    callBack.call(tmp.get(), bitmap);
                    if (tmp.get() == imgIdArr.length - 1) {
                        doneCallBack.call();
                    }
                    tmp.getAndSet(tmp.get() + 1);
                }
            });
        }
    }

    public static void UrlToBitmap(Context context, String imageUrl, String imageId, HJMHelper hjmHelper, HjmObjectCallBack<Bitmap> callBack) {
        Executors.newSingleThreadExecutor().submit(()->{
            String[] imgIdArr = new String[]{imageId};
            // 获取图片id不在数据库中的图片id数组
            String[] imgIdNotInDBArr = ImgTableTool.findImgIdNotInDBArr(imgIdArr, hjmHelper);

            if (imgIdNotInDBArr.length == 0) {
                // 图片id在数据库中
                Bitmap bitmap = ImgTableTool.findImgById(imageId, hjmHelper);
                callBack.call(true, bitmap, null);
            } else {
                OkHttpClient client = new OkHttpClient();

                getBitMapByOkHTTP(client, imageUrl + imageId, context,
                        (isSuccess, bitmap, msg) -> {
                            if (isSuccess) {
                                callBack.call(true, bitmap, null);
                                try {
                                    ImgTableTool.insert(imageId, bitmap, hjmHelper);
                                } catch (Exception e) {
                                    Log.d(TAG, "UrlToBitmap: 插入失败");
                                }
                            } else {
                                callBack.call(true, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01), null);
                            }
                        });
            }
        });
    }

    public static void UrlToBitmap(Context context, String imageUrl, HjmObjectCallBack<Bitmap> callBack) {
        Glide.with(context)
                .asBitmap()
                .load(imageUrl)
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition<? super Bitmap> transition) {
                        // 在这里处理获取到的Bitmap对象
                        callBack.call(true, bitmap, null);
                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        super.onLoadFailed(errorDrawable);
                        Log.e(TAG, "onLoadFailed: 获取图片失败");
                        callBack.call(false, null, "获取图片失败");
                    }
                });
    }

    public static void UrlToDrawable(Context context, String imageUrl, HjmObjectCallBack<Drawable> callBack) {

        Glide.with(context)
                .load(imageUrl)
                .into(new SimpleTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable drawable, @Nullable Transition<? super Drawable> transition) {
                        // 在这里处理获取到的Drawable对象
                        callBack.call(true, drawable, null);
                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        super.onLoadFailed(errorDrawable);
                        Log.e(TAG, "onLoadFailed: 获取图片失败");
                        callBack.call(false, errorDrawable, "获取图片失败");
                    }
                });
    }

    /**
     * 使用OkHttpClient获取图片
     *
     * @param client   需要
     * @param imageUrl 图片链接
     * @param context  上下文
     * @param callBack 回调
     */
    public static void getBitMapByOkHTTP(OkHttpClient client, String imageUrl, Context context, HjmGlideBitmapCallBack callBack) {

        Request request = new Request.Builder()
                .url(imageUrl)  // 图片链接
                .build();

        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                InputStream inputStream = response.body().byteStream();
                callBack.call(0, BitmapFactory.decodeStream(inputStream));
            } else {
                // 处理请求失败的情况，将资源目录下的Drawable转为Bitmap
                callBack.call(0, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
            }
        } catch (IOException e) {
            // 处理异常
            callBack.call(0, BitmapFactory.decodeResource(context.getResources(), R.drawable.keli01));
        }
    }

    public static void getBitMapByOkHTTP(OkHttpClient client, String imageUrl, Context context, HjmObjectCallBack<Bitmap> callBack) {

        Request request = new Request.Builder()
                .url(imageUrl)  // 图片链接
                .build();

        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                InputStream inputStream = response.body().byteStream();
                callBack.call(true, BitmapFactory.decodeStream(inputStream), null);
            } else {
                // 处理请求失败的情况，将资源目录下的Drawable转为Bitmap
                callBack.call(false, null, "获取图片失败");
            }
        } catch (IOException e) {
            // 处理异常
            callBack.call(false, null, "获取图片失败 " + e.getMessage());
        }
    }

    /**
     * 将Bitmap转为Base64
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // TODO:要分析bitmap是什么格式的图片?
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] bytes = baos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

    public interface HjmGlideBitmapCallBack {
        void call(int position, Bitmap bitmap);
    }

    public interface HjmGlideDrawableCallBack {
        void call(int position, Drawable drawable);
    }

    public interface HjmGlideDoneCallBack {
        void call();
    }
}
